package org.jeecg.modules.online.desform.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtil;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.MatchTypeEnum;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.online.desform.constant.DesformConstant;
import org.jeecg.modules.online.desform.entity.DesignForm;
import org.jeecg.modules.online.desform.entity.DesignFormData;
import org.jeecg.modules.online.desform.service.IDesignFormAuthService;
import org.jeecg.modules.online.desform.service.IDesignFormDataService;
import org.jeecg.modules.online.desform.service.IDesignFormService;
import org.jeecg.modules.online.desform.vo.DesignFormPage;
import org.jeecg.modules.online.desform.vo.TranslateData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @Description: 表单设计
 * @Author: jeecg-boot
 * @Date: 2019-05-16
 * @Version: V1.0
 */
@RestController("designFormController")
@RequestMapping("/desform")
@Slf4j
public class DesignFormController {

	@Autowired
	private IDesignFormService designFormService;
	@Autowired
	private IDesignFormDataService designFormDataService;
    @Autowired
    private IDesignFormAuthService designFormAuthService;

	/**
	 * 分页列表查询
	 *
	 * @param designForm
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@GetMapping(value = "/list")
	public Result<?> queryPageList(DesignForm designForm, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
		Map<String, String[]> parameterMap = req.getParameterMap();
		QueryWrapper<DesignForm> queryWrapper = QueryGenerator.initQueryWrapper(designForm, parameterMap);

		//TODO 是否按照用户进行数据隔离查询，不需要则注释下面代码
		String token = TokenUtils.getTokenByRequest(req);
		String userName =  JwtUtil.getUsername(token);
		//queryWrapper.eq("create_by",userName);

		List<DesignForm> designFormList;
		IPage<DesignFormPage> voPage = new Page<>(pageNo, pageSize);
		String[] parentId = parameterMap.get("parentId");
		boolean hasParentId = (parentId != null && parentId.length > 0 && !StringUtil.isEmpty(parentId[0]));

		// 传入了父ID，表明是子表
		if (hasParentId) {
			// 子表直接查询所有，不分页
			designFormList = designFormService.list(queryWrapper);
		} else {
			queryWrapper.isNull("parent_id");

			Page<DesignForm> page = new Page<DesignForm>(pageNo, pageSize);
			IPage<DesignForm> pageList = designFormService.page(page, queryWrapper);
			designFormList = pageList.getRecords();

			voPage.setTotal(pageList.getTotal());
		}

		// 将 DesignForm 都 copy 成 DesignFormPage
		List<DesignFormPage> list = new ArrayList<>();
		for (DesignForm record : designFormList) {

			DesignFormPage designFormPage = new DesignFormPage();
			BeanUtils.copyProperties(record, designFormPage);

			// 最多两个层级
			if (hasParentId) {
				designFormPage.setHasChildren(false);
			} else {
				queryWrapper = new QueryWrapper<>();
				queryWrapper.eq("parent_id", record.getId());
				boolean hasChildren = (designFormService.count(queryWrapper) > 0);
				designFormPage.setHasChildren(hasChildren);
			}

			list.add(designFormPage);
		}

		voPage.setRecords(list);
		return Result.ok(voPage);
	}

	/**
	 * 添加
	 *
	 * @param designFormPage
	 * @return
	 */
	@PostMapping(value = "/add")
	public Result<DesignForm> add(@RequestBody DesignFormPage designFormPage, HttpServletRequest req) {
		Result<DesignForm> result = new Result<DesignForm>();
		try {
			DesignForm designForm = new DesignForm();
			BeanUtils.copyProperties(designFormPage, designForm);
			//获取登录人
			String token = TokenUtils.getTokenByRequest(req);
			String userName =  JwtUtil.getUsername(token);
			designForm.setCreateBy(userName);
			designFormService.saveMain(designForm);

			//修改默认移动视图逻辑【只保留一个默认移动视图】
			if (DesformConstant.IS_MOBILE_VIEW_Y.equals(designForm.getIzMobileView())) {
				String parentCode = designForm.getDesformCode();
				if (DesformConstant.DESFORM_TYPE_SV.equals(designForm.getDesformType())) {
					parentCode = designForm.getParentCode();
				}
				designFormService.updateDefMobileViewStatus(parentCode, designForm.getDesformCode());
			}
			result.success("添加成功！");
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			result.error500("操作失败");
		}
		return result;
	}

	/**
	 * 编辑
	 *
	 * @param designFormPage
	 * @return
	 */
	@PutMapping(value = "/edit")
	public Result<DesignForm> edit(@RequestBody DesignFormPage designFormPage) {
		Result<DesignForm> result = new Result<DesignForm>();
		DesignForm designForm = new DesignForm();
		BeanUtils.copyProperties(designFormPage, designForm);
		DesignForm designFormEntity = designFormService.getById(designForm.getId());
		if (designFormEntity == null) {
			result.error500("未找到对应实体");
		} else {
            String desformCode = designFormEntity.getDesformCode();
			designFormService.updateById(designForm);
			//修改默认移动视图逻辑
            if (DesformConstant.IS_MOBILE_VIEW_Y.equals(designForm.getIzMobileView())) {
                String parentCode = designFormEntity.getDesformCode();
                if (DesformConstant.DESFORM_TYPE_SV.equals(designFormEntity.getDesformType())) {
                    parentCode = designFormEntity.getParentCode();
                }
                designFormService.updateDefMobileViewStatus(parentCode, desformCode);
            }
			result.success("修改成功!");
		}

		return result;
	}

	/**
	 * 通过id删除
	 *
	 * @param id
	 * @return
	 */
	@DeleteMapping(value = "/delete")
	public Result<DesignForm> delete(@RequestParam(name = "id", required = true) String id) {
		Result<DesignForm> result = new Result<DesignForm>();
		DesignForm designForm = designFormService.getById(id);
		if (designForm == null) {
			result.error500("未找到对应实体");
		} else {
			designFormService.delMain(id);
			result.success("删除成功!");
		}

		return result;
	}

	/**
	 * 批量删除
	 *
	 * @param ids
	 * @return
	 */
	@DeleteMapping(value = "/deleteBatch")
	public Result<DesignForm> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
		Result<DesignForm> result = new Result<DesignForm>();
		if (ids == null || "".equals(ids.trim())) {
			result.error500("参数不识别！");
		} else {
			this.designFormService.delBatchMain(Arrays.asList(ids.split(",")));
			result.success("删除成功!");
		}
		return result;
	}

    /**
     * 查询列，同时查询按钮权限
     * @param desformCode
     * @param request
     * @return
     */
    @GetMapping(value = "/getColumns")
    public Result getColumns(@RequestParam(name = "desformCode") String desformCode, HttpServletRequest request) {
        Result<DesignForm> result = this.queryByCode(desformCode);
        if (result.isSuccess()) {
            // 查询按钮权限
            String username = JwtUtil.getUserNameByToken(request);
            JSONObject buttonsAuth = designFormAuthService.queryButtonsAuth(desformCode, username);
            // 封装返回对象
            JSONObject res = new JSONObject();
            res.put("designForm", result.getResult());
            res.put("buttonsAuth", buttonsAuth);
            return Result.ok(res);
        }
        return result;
    }

    /**
     * 翻译列数据
     */
    @PutMapping(value = "/translateColumns")
    public Result translateColumns(@RequestBody List<TranslateData> translateDataList) {
        if (translateDataList != null && translateDataList.size()>0) {
            Map<String, List<DictModel>> translateObject = designFormService.translateColumns(translateDataList);
            return Result.ok(translateObject);
        }
        return Result.error("translateDataList不能为空");
    }

	/**
	 * 通过 code 查询
	 *
	 * @param desformCode
	 * @return
	 */
	@GetMapping(value = "/queryByCode")
	public Result<DesignForm> queryByCode(@RequestParam(name = "desformCode", required = true) String desformCode) {
		Result<DesignForm> result = new Result<DesignForm>();
		DesignForm designForm = designFormService.getByCode(desformCode);
		if (designForm == null) {
			result.error500("未找到对应实体");
		} else {
			result.setResult(designFormService.queryAllDictItem(designForm));
			result.setSuccess(true);
		}
		return result;
	}

	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/queryById")
	public Result<DesignForm> queryById(@RequestParam(name = "id", required = true) String id) {
		Result<DesignForm> result = new Result<DesignForm>();
		DesignForm designForm = designFormService.getById(id);
		if (designForm == null) {
			result.error500("未找到对应实体");
		} else {
			result.setResult(designFormService.queryAllDictItem(designForm));
			result.setSuccess(true);
		}
		return result;
	}

	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@GetMapping(value = "/queryDesignFormDataByMainId")
	public Result<List<DesignFormData>> queryDesignFormDataListByMainId(@RequestParam(name = "id", required = true) String id) {
		Result<List<DesignFormData>> result = new Result<List<DesignFormData>>();
		List<DesignFormData> designFormDataList = designFormDataService.selectByMainId(id);
		result.setResult(designFormDataList);
		result.setSuccess(true);
		return result;
	}

	/**
	* 同步索引
	*/
    @PutMapping("/redoAllIndex")
    public Result redoAllIndex(@RequestBody JSONObject formData) {
		String rowIds = oConvertUtils.getString(formData.get("selections"));
		Integer pageSize = formData.getInteger("pageSize");
		log.info("selections: "+ rowIds);
		return designFormService.redoAllIndex(rowIds, pageSize, false);
    }

	/**
	 * 强制同步索引
	 */
    @PutMapping("/redoAllIndexForce")
    public Result redoAllIndexForce(@RequestBody JSONObject formData) {
		String rowIds = oConvertUtils.getString(formData.get("selections"));
		Integer pageSize = formData.getInteger("pageSize");
		log.info("selections: "+ rowIds);
		return designFormService.redoAllIndexForce(rowIds, pageSize);
    }

	/* ------------- Begin 开放API接口 ------------- */

	/**
	 * 通过 desformCode 和 dataId 查询数据
	 *
	 * @param desformCode
	 * @param dataId
	 * @return
	 */
	@GetMapping("/api/{desformCode}/{dataId}")
	public Result apiGetData(@PathVariable("desformCode") String desformCode,
			                 @PathVariable("dataId") String dataId) {
		LambdaQueryWrapper<DesignFormData> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(DesignFormData::getId, dataId);
		queryWrapper.eq(DesignFormData::getDesformCode, desformCode);
		DesignFormData result = designFormDataService.getOne(queryWrapper);
		if (result != null) {
			return Result.ok(JSON.parseObject(result.getDesformDataJson()));
		} else {
			return Result.ok(null);
		}
	}

	/**
	 * 通过 desformCode 和 dataId 查询数据
	 *
	 * @param desformCode
	 * @return
	 */
	@GetMapping("/api/{desformCode}/list")
	public Result apiGetDataList(
			@PathVariable("desformCode") String desformCode,
			@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
			@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
			@RequestParam(name = "matchType", required = false, defaultValue = "and") String matchType,
			@RequestParam(name = "queryRules", required = false, defaultValue = "[]") String queryRules
	) {
		MatchTypeEnum matchTypeMenu = MatchTypeEnum.getByValue(matchType);
		if (matchTypeMenu == null) {
			return Result.error("matchType只能为'and'或'or'");
		}
		JSONArray queryRulesJSON = JSON.parseArray(queryRules);

		// 将表单数据遍历出来
		Result<IPage<DesignFormData>> result = designFormDataService.pageList(desformCode, pageNo, pageSize, new QueryWrapper<>(), queryRulesJSON, matchTypeMenu);
		List<DesignFormData> records = result.getResult().getRecords();
		JSONArray formDataArray = new JSONArray(records.size());
		for (DesignFormData record : records) {
			JSONObject data = JSON.parseObject(record.getDesformDataJson());
			data.put("id", record.getId());
			data.put("desformId", record.getDesformId());
			data.put("desformCode", record.getDesformCode());
			formDataArray.add(data);
		}
		Result<JSONArray> res = new Result<>();
		res.setCode(result.getCode());
		res.setMessage(result.getMessage());
		res.setResult(formDataArray);
		return res;
	}

	/**
	 * 通过 desformCode 新增数据
	 *
	 * @param desformCode
	 * @param formData
	 * @return
	 */
	@PostMapping("/api/{desformCode}")
	public Result apiAddData(
			@PathVariable("desformCode") String desformCode,
			@RequestBody JSONObject formData
	) {
		if (formData == null) {
			return Result.error("formData 不能为空");
		}
		DesignFormData entity = new DesignFormData();
		entity.setDesformCode(desformCode);
		entity.setDesformDataJson(formData.toJSONString());
		return designFormDataService.addOne(entity);
	}

	/**
	 * 通过 desformCode 和 dataId 修改数据
	 *
	 * @param desformCode
	 * @param dataId
	 * @param formData
	 * @return
	 */
	@PutMapping("/api/{desformCode}/{dataId}")
	public Result apiEditData(
			@PathVariable("desformCode") String desformCode,
			@PathVariable("dataId") String dataId,
			@RequestBody JSONObject formData
	) {
		if (formData == null) {
			return Result.error("formData 不能为空");
		}
		DesignFormData entity = new DesignFormData();
		entity.setId(dataId);
		entity.setDesformCode(desformCode);
		entity.setDesformDataJson(formData.toJSONString());
		return designFormDataService.editOne(entity);
	}

	/**
	 * 通过 desformCode 和 dataId 删除数据
	 *
	 * @param desformCode
	 * @param dataId
	 * @return
	 */
	@DeleteMapping("/api/{desformCode}/{dataId}")
	public Result apiDeleteData(
			@PathVariable("desformCode") String desformCode,
			@PathVariable("dataId") String dataId,
			HttpServletRequest request
	) {
		DesignFormData entity = new DesignFormData();
		entity.setId(dataId);
		entity.setDesformCode(desformCode);
		return designFormDataService.deleteOne(entity, TokenUtils.getTokenByRequest(request));
	}

	/* -------------  End  开放API接口 ------------- */

}
